<!DOCTYPE html>
     <html>
         <head>
           <meta charset="utf-8" />
		   <title>双向列表</title>
    <style>
    html,body {
            padding: 0;
            margin: 0;
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 14px;
            color: #333;
   }
    .outBox {
            width: 500px;
            height: 220px;
            border: 3px double #eee;
            display: flex;
            padding: 0 20px;
            align-items: center;
   }
    .list {
          width: 120px;
          height: 200px;
          flex: none;
          display: flex;
          flex-direction: column;
   }
   .title {
         font-size: 16px;
          flex: none;
         padding: 5px 0;
     }
      .listBox {
        flex: 1;
        padding: 5px;
        border: 1px solid #eee;
        overflow-y: auto;
   }
    .oneData {
        box-sizing: border-box;
        cursor: pointer;
        padding: 2px 5px;
        line-height: 1;
        border-radius: 2px;
        transition: 0.2s ease;
        border: 1px solid rgba(0, 0, 0, 0);
        text-overflow: ellipsis;
        overflow: hidden;
        white-space: nowrap;
    }
    .oneData.selected {
     background: #b2adef;
     color: #fff;
    }
    .oneData:hover {
     border: 1px solid #b2adef;
   }
      .oneData:not(:first-child) {
     margin-top: 5px;
     }
    .buttonBox {
     flex: 1;
     display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
   }
     .button {
       font-size: 12px;
       cursor: pointer;
        user-select: none;
        padding: 2px 6px;
         border-radius: 4px;
         border: 1px solid #8b82f8;
         background: #6961c8;
          color: #fff;
              transition: 0.2s ease;
   }
   .button:hover {
	border: 1px solid #6961c8;
	background: #8b82f8;
}
            .button:not(:first-child) {
             margin-top: 5px;
           }
            </style>
           </head>
           <body>
       <div class="outBox">
        <div class="list">
          <div class="title">Selected</div>
          <div id="selected" class="listBox">
      </div>
</div>
    <div class="buttonBox">
         <div class="button" id="add">add</div>
<div class="button" id="remove">remove</div>
   </div>
     <div class="list">
    <div class="title">to be selected</div>
     <div id="noselect" class="listBox">
            </div>
        </div>
</div>
</body>
<script>
     let add = document.getElementById('add')
     let remove = document.getElementById('remove')
     let selected = document.getElementById('selected')
     let noselect = document.getElementById('noselect')
     let dataList = Array.from({length: 10}, (_, index) => ({id: index, label: `数据${index + 1}`}))
     let noselectList = [...dataList] // 未选入data
     let selectList = [] // 已选入data
     let addList = new Set() // 选中需要移入的id
     let removeList = new Set() // 选中需要移出的id
   // 选中、取消选中
         const setSelect = (data, isRight) => {
     if (isRight) {
       removeList.clear()
       if (addList.has(data.id)) {
    addList.delete(data.id)
          } else {
        addList.add(data.id)
      } 
           } else {
        addList.clear()
          if (addList.has(data.id)) {
           removeList.delete(data.id)
            } else {
          removeList.add(data.id)
        }
 }
      reset()
}
// 移入
       add.addEventListener('click', () => {
       if (addList.size > 0) {
         let newLeft = []
           let newRight = []
       noselectList.forEach(ele => {
             if (addList.has(ele.id)) {
           newLeft.push(ele)
           } else {
          newRight.push(ele)
    }
       })
          selectList = newLeft.concat(selectList)
noselectList = newRight
addList.clear()
reset()
}
})
//移出
     remove.addEventListener('click', () => {
    if (removeList.size > 0) {
       let newLeft = []
    let newRight = []
     selectList.forEach(ele => {
      if (removeList.has(ele.id)) {
         newRight.push(ele)
} else {
newLeft.push(ele)
}
})
         selectList = newLeft
         noselectList = newRight.concat(noselectList)
removeList.clear()
reset()
}
})
// 重新生成内容
const reset = () => {
// 左边区域
let leftList = selectList.map(ele => {
      return model(ele)
    }).join('')
selected.innerHTML = leftList
    // 右边边区域
let rightList = noselectList.map(ele => {
return model(ele, true)
}).join('')
noselect.innerHTML = rightList
}
// 模板
           const model = (data, isRight) => {
             let selected = (isRight && addList.has(data.id)) || removeList.has(data.id)
        return `<div class="oneData ${selected ? 'selected' : ''}" title="${data.label}" onclick='setSelect(${JSON.stringify(data)}, ${isRight})'>
         ${data.label}
    </div>`
} 
reset()
          </script>
 </html>






































<!-- <html>
	 <head>
	<meta charset="utf-8">
	<title>双向列表</title>
	<style type="text/css">
		*{padding: 0px;margin: 0px;}
		html,body{width: 100%;height: 100%;font-family: "微软雅黑";background: #b1b1b1;}
		ul,li{list-style: none;}
		.container{
			width:560px;
			height: 400px;
			padding: 40px 20px;
			background: #fff;
			border-radius: 4px;	
			position: absolute;
			left: 50%;
			top: 50%;
			margin-left: -280px;
			margin-top: -200px;
		}
		.container ul.data-list{width: 40%;height: 100%;border: 1px solid #e5e5e5;float: left;}
		.container ul.data-list li{line-height: 32px;padding: 0px 10px;}
		.container ul.data-list li:hover{ background-color: #C5EFFF; color: #252525; cursor: pointer; font-weight: bold; }
		.container ul.data-list li.selected{ background-color: #0095E8; color: #fff; }
		.button-box{float: left;width: 19%;height: 50%;margin-top: 20%;}
		.button-box button{
			background: none;
			font-size: 16px;
			border: 1px solid #818181;
			color: #359bf5;height: 36px;
			line-height: 36px;width: 80%;
			margin: 10px auto;
			display: block;
			cursor: pointer;
		}
	</style>
</head>
<body>
	<div class="container">
		
		<ul class="data-list" id="lList">
			<li>第一行选择文字1</li>
			<li>第二行选择文字2</li>
			<li>第三行选择文字3</li>
			<li>第四行选择文字4</li>
			<li>第五行选择文字5</li>
			<li>第六行选择文字6</li>
			<li>第一行选择文字7</li>
			<li>第二行选择文字8</li>
		</ul>
		
		<div class="button-box">
			<button type="button" name="button" id="add">add</button>
			<button type="button" name="button" id="remove">delect</button>
		</div>
		<ul class="data-list" id="rList">
 
		</ul>
		
	</div>
	<script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
	<script type="text/javascript">
		$(function(){
			var lList = $("#lList");
			var llList = document.getElementById("lList");
			var rList = $("#rList");
			var items = $(".data-list li");
			for(var i = 0;i<items.length;i++){
				items[i].onclick = itemsclick;
				items[i].ondblclick = itemsdblclick;
			}
			function itemsdblclick(){
				if (this.parentNode === llList) {
					rList.append(this);
				}else{
					lList.append(this);
				}
			}
			function itemsclick(){
				var classname = this.className;
				if(classname === "selected"){
					this.className = "";
				}else{
					this.className="selected";
				}
			}

			function itemsMove(){ 
				var items = $(".data-list li.selected");
				for(var i = 0;i<items.length;i++){
					if(this.id === "add"){
						rList.append(items[i]);
					}else{
						lList.append(items[i]);
					}
				}
			}
			$("#add").on("click",itemsMove);
			$("#remove").on("click",itemsMove);
		});
		
	</script>
 
</body>
</html>




